import { HttpException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './user.entity';
import { In, Repository } from 'typeorm';
import { Logs } from 'src/logs/logs.entity';
import { getUserDto } from './dto/get-user.dto';
import { Roles } from 'src/roles/roles.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User) private readonly userRepository: Repository<User>,
    @InjectRepository(Logs) private readonly logsRepository: Repository<Logs>,
    @InjectRepository(Roles) private readonly rolesRepository: Repository<Roles>,
  ) { }

  async findAll(query: getUserDto) {
    const { limit = 10, page = 1, username, gender, role } = query
    // return await this.userRepository.find({
    //   select: {
    //     id:true,
    //     username: true,
    //     profile: {
    //       gender: true
    //     }
    //   },
    //   relations: {
    //     profile: true,
    //     roles: true
    //   },
    //   where: {
    //     username,
    //     profile: {
    //       gender,
    //     },
    //     roles: {
    //       id: role,
    //     }
    //   },
    //   take: limit,
    //   skip: (page - 1) * limit
    // })
    return this.userRepository.createQueryBuilder('user')
      .leftJoinAndSelect('user.profile', 'profile')
      .leftJoinAndSelect('user.roles', 'roles')
      // .where('user.username = :username', { username })
      // .andWhere('profile.gender = :gender', { gender })
      // .andWhere('roles.id = :role', { role })
      .where(username ? 'user.username = :username' : '1=1', { username })
      .andWhere(gender ? 'profile.gender = :gender' : '1=1', { gender })
      .andWhere(role ? 'roles.id = :role' : '1=1', { role })
      .take(limit)
      .skip((page - 1) * limit)
      .getMany()
  // }
  }

  find(username: string) {
    return this.userRepository.findOne({ where: { username }, relations: ['roles'] })
  }

  async create(user: Partial<User>) {
    if (!user.roles) {
      const role = await this.rolesRepository.findOne({
        where: {
          id: 2
        }
      })
      user.roles = [role as Roles]
    }
    if (user.roles instanceof Array && typeof user.roles[0] === 'number') {
      user.roles = await this.rolesRepository.find({
        where: {
          id: In(user.roles)
        }
      })
    }
    const tmp = await this.userRepository.create(user)
    return this.userRepository.save(tmp)
  }

  async update(id: number, user: Partial<User>) {
    // return this.userRepository.update(id, user)
    const userTmp = await this.findProfile(id)
    if (userTmp) {
      const newUser = this.userRepository.merge(userTmp, user)
      return this.userRepository.save(newUser)
    }
    // return this.userRepository.update(id, user)
  }

  async remove(id: number) {
    const user = await this.userRepository.findOne({ where: { id } })
    if (user) return this.userRepository.remove(user)
      throw new HttpException('用户不存在', 404)
  }

  findProfile(id: number) {
    return this.userRepository.findOne({
      where: { id },
      relations: {
        profile: true,
        logs: true,
        roles: true
      }
    })
  }

  findLogs(id: number) {
    const user = this.userRepository.findOne({ where: { id } })
    return this.logsRepository.find({
      where: {
        user
      },
      relations: {
        user: true
      }
    })
  }

  findLogsByGroup(id: number) {
    return this.logsRepository
      .createQueryBuilder('logs')
      .select('logs.result', 'result')
      .addSelect('COUNT("logs.result")', 'count')
      .where('logs.userId = :id', { id })
      // .leftJoinAndSelect('logs.user', 'user')
      // .where('user.id = :id', { id })
      .groupBy('logs.result')
      .getRawMany()

  }
}
